■ グラフィック液晶制御(GDDXグラフィックライブラリ 編)
■ GDDXタッチパネル式 wav録音付MP3プレーヤ
タッチパネル式のWAV録音機能付きのMP3プレーヤの試作例を紹介します。 液晶グラフィック制御には、マイクロチップのGDDX(Graphics Display Designer X) を
つかっています。
MP3のデコーダーICとしてはVS1011Eを使用しています。 VS1011Eのライブラリ関数(VS1011.h、VS1011.c)は後閑哲也さんが設計されたものです。後閑さんには
本プレーヤー製作にあたり貴重なアドバイスを多々いただきました。
<試作品仕様>
・ グラフィック液晶を用いたMP3プレーヤとする。
・ SDカードのルートディレクトリにあるファイルを最大10個表示のこと
ファイルが10個以上あってもスクロールして表示できなくてもよい
サブフォルダのファイルは表示しない。
SDカードは マイクロチップのMDDライブラリを使用すること
SDカードの書込み速度class 10 を用いること(書込み速度の遅いSDカードを用いると録音に飛びがでて音質低下をまねきます。)
・ グラフィッ液晶は Displaytec Ltd INT035TFT QVGA 3.5インチ とする。
表示インターフェース:8080 16bit パラレル (LCDコントローラ Solomon Systech SSD1963)
タッチインターフェース: SPI (タッチパネルIC Maxim MAX11802)
グラフィックライブラリは GDDX(Graphics Display Designer X)によるマイクロチップグラフィックライブラリを用いること
液晶画面のデザイン設計は<GDDX デザイン画面>によりおこなうこと
・キャラクタ液晶は SC1602 16文字×2行を使用のこと
キャラクタ液晶には、再生中のファイル名、タッチ位置の座標、音量を表示のこと
・音量は 液晶画面上にスライダーウィジェットを描画してこのツマミをドラッグして変えられること
・MP3デコーダは VLSI solution Ltd VS1011E (販売先:秋月電子)を用いること
・MP3ライブラリは: 後閑哲也氏設計の MP3ライブラリを用いること
・録音に係る仕様は以下とする。
@圧縮のフォーマットID …… リニアPCM
Aチャンネル数 …… モノラル
Bサンプリングレート……22050 Hz
Cデータ転送速度 ……44100 バイト/sec
DBlock align …… 2 バイト/サンプル
E量子化ビット数……16ビット
・録音するファイル名はVOICE.wavとする。SDカード内のルートにこのファイル名のファイルが存在しない場合はファイルをつくること。 また、
すでにVOICE.wavが存在する場合は上書きするものとする。
・録音の開始・停止は 液晶画面を操作するのではなく、外部スイッチとする。
<GDDX デザイン画面>
<試作品回路図>(→回路図のPDFファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
<プログラム例> //Main.c //GDDXタッチパネル式 wav録音付MP3プレーヤ #include <p32xxxx.h> #include <plib.h> // PIC32 peripheral library #include "1lcd_lib_C32.h" #include "FSIO.h" #include "VS1011.h" #include "Main.h" #include "GDD_Screens.h" // Configuration bits//システムクロック:80MHz ペリフェラルクロック:80MHz #pragma config FPLLODIV = DIV_1, FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FWDTEN = OFF, FCKSM = CSECME, FPBDIV = DIV_1 #pragma config OSCIOFNC = ON, POSCMOD = XT, FSOSCEN = ON, FNOSC = PRIPLL #pragma config CP = OFF, BWP = OFF, PWP = OFF //WAVEファイルヘッダ構造体定義 struct myWaveHeader //全ヘッダサイズ: 44バイト { char id_RIFF[4]; //Chunk ID RIFFヘッダ // 4バイト unsigned int size_file; //ファイルサイズ(総ファイルサイズ - 8)バイト //4バイト char id_WAVE[4]; //Chunk ID WAVE //4バイト char id_fmt[4]; //Chunk ID fmt //4バイト unsigned int size_fmt; //フォーマット関連定義データのサイズ //4バイト unsigned short int code_wavefmt; //WAVEファイルの圧縮フォーマットコード 但し、リニアPCMは圧縮なし//2バイト unsigned short int channel; //チャンネル数 //2バイト unsigned int rate_sample; //サンプリングレート //4バイト unsigned int rate_tranfer; //転送速度[byte/sec] //4バイト unsigned short int align_block; //サンプルあたりのバイト数[byte/サンプル] //2バイト unsigned short int bit_sample; //量子化ビット数[bit] //2バイト char id_data[4]; //Chunk ID data //4バイト unsigned int size_data; //サンプリングデータのサイズ[byte] //4バイト }; struct myWaveHeader mywaveheader = // WAVEファイルヘッダ構造体の初期化 //44バイト { "RIFF", //Chunk ID RIFF // 4バイト 0x0006C28C, //(仮)ファイルサイズ: 443020バイト //特に値に意味なし "WAVE", //Chunk ID WAVE //4バイト "fmt ", //char id_fmt[4]; //Chunk ID fmt //4バイト 16, //16バイト at リニアPCM フォーマット関連定義データのサイズ //4バイト 0x0001, //WAVEファイルの圧縮フォーマットコード: リニアPCM //2バイト 1, //チャンネル数: モノラル //2バイト 22050, //サンプリングレート: 22.05[KHz] //4バイト 44100, //転送速度: 44100[byte/sec] //4バイト //サンプリングレート: 22.05[Hz] 2, //サンプルあたりのバイト数: 2[byte]/サンプル //2バイト 16, //量子化ビット数: 16[bit] //2バイト "data", //Chunk ID data //4バイト 0x0006C267 ////(仮)サンプリングデータのサイズ: 442983バイト //特に値に意味なし }; struct myWaveHeader* ptrWH; //構造体のポインタ // FATファイル用構造体のポインタ変数 FSFILE* pfile; //SDカードのファイルポインタ SearchRec Record; SearchRec *rptr = &Record; int i; BYTE Buffer[256]; int myResult; char File_Name[30][13]; //8 + 3 + 1 +1 = 13 char* str_filename; int N_Item; long int Position; //ファイルポインタ位置 size_t N_Write; // MP3用変数 BYTE Volume, ChgFlag, BASS; int Mode_PlayRecord = 0; //0:再生 1:録音 unsigned int adr_SD,adr_nowSD; unsigned int count_block = 0; //SD送信ブロック(512バイト)数 unsigned int size_dataBlock = 512; int count_buf0 = 0; //バッファ0データ数 int count_buf1 = 0; //バッファ1データ数 int flag_buf0 = 0; //音声データバッファ0の状態 int flag_buf1 = 0; //音声データバッファ1の状態 // 0:音声データ受信可能状態 1:SDへ音声データ送信可能状態 int mode_tranceive = 0; //送受信モード //0: バッファ1=音声タ受信、バッファ2=SD送信 //1: バッファ1=SD送信モード、バッファ2=音声受信 short int data0_sound[512]; //音声データバッファ1 short int data1_sound[512]; //音声データバッファ2 int Stop_SDwriting = 0;// 1: SDカードへの書込み停止 0: 書込み許可 char strFile[16]; char Buf[17]; //文字列のバッファー用レジスタ char textBuf[64]; volatile DWORD tick = 0; // tick counter int Mode_Btn1; int Change_Btn1; unsigned int BtnCount = 0; int Started_Osc = 0; int Record_First = 0; int Recording_Voice = 0; unsigned int temp1_ad; int temp2_ad; int GOL_First = 0; //GOLに係る追加の初期化 extern int updateListBox; //リストボックスアイテム選択 int PosSld; //スライダ位置(0-100) extern int Press_BTN_1; int Count_BTN_1 = 0; //ボタンBTN_1 チャタリング防止カウンタ int Playing = 0; int ix; LISTITEM *pAddedItem,*pAddedItem0; // 関数のプロトタイプ宣言 void TickInit(void); // starts tick counter //-------------------------------------------------------------------------------------------------------- // ・ SSD1926.h, SSD1926.c,TCON_SSD1289.c --> INT035TFT_lib.h, INT035TFT_li.c // ・ DisplayResetDisable(); DisplayResetConfig(); DelayMs(2000); 500msec以上の遅れ追加 // ・ TouchScreenResistive.h TouchScreenResistive.c --> MAX11802_lib.h MAX11802_lib.c // ・ 不要: //TouchScreen.cを削除すると コンパイルエラーがでる // ・ 1lcd_lib_C32.h, 1lcd_lib_C32.c 追加 // ・ DDPCONbits.JTAGEN = 0; //I/OポートとしてRA0、RA1、RA4、RA5をつかう場合、電源投入後DDPCONレジスタのbit3を0に、設定する必要があり;ます。 // ・ OpenTimer4(T4_ON | T4_PS_1_8, TICK_PERIOD) --> OpenTimer4(T4_ON | T4_PS_1_256, 31249); //35μsec -->99.99 msec //---------------------------------------------------------------------------------- //------------------------------------------------------------------------------ void delay_us(unsigned int usec) //1μsec遅延関数 { int count; count = (int)(Clock/20000000)*usec; do //実測: at Clock=80000000 { //delay_us(1000)→1003μsec、 delay_us(100)→102μsec、delay_us(10)→11μsec、delay_us(1)→1.6μsec asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); count--; }while(count != 0); } //------------------------------------------------------------------------------ void delay_ms(unsigned int msec) //1msec遅延関数 { unsigned int i; for(i=0; i<msec; i++) delay_us(1000); } void myGOLInit() //GDDXデザイナでは、設定(初期化)できないGOLオブジェクト項目の設定(初期化) { GOL_First = 1; LISTBOX *pLB = (LISTBOX*)GOLFindObject( LSB_1 ); //get ListBox object pLB->hdr.state = LB_DRAW | LB_CENTER_ALIGN | LB_SINGLE_SEL; // LB_SINGLE_SEL:1つのアイテムを選択 LbDelItemsList(pLB); //すべてのアイテムを消去//カレントアイテムをなしにする//addアイテムでitemを先頭にもってくる for(ix = 0; ix <= 9; ix++) //表示ファイル数=10 // for(ix = 0; ix <= N_Item; ix++) { pAddedItem = LbAddItem( pLB, NULL, &File_Name[ix][0] , NULL, 0, 0); //ファイル名をリストに順次追加 if(ix == 0) { pAddedItem0 = pAddedItem; LbSetSel(pLB, pAddedItem0); //アイテム0を選択 LbSetFocusedItem(pLB,0); //アイテム0にフォーカスをセット str_filename = &File_Name[0][0]; pfile = FSfopen(str_filename, "r"); } } SetState( pLB, LB_DRAW); //エディットボックスのタイトル修正 EDITBOX *pEb = (EDITBOX*)GOLFindObject(EDB_1); //エディットボックスのオブジェクト検出 XCHAR *ptext; sprintf(textBuf,"MP3 player on PIC32MX795F512L"); ptext = &textBuf[0]; EbSetText(pEb,ptext); SetState(pEb, EB_DRAW); } //------------------------------------------------------------------------------ void SkipFile(void) //演奏ファイルのスキップ { FSfclose(pfile); // 現在のファイルを強制クローズ PlayEnd(); // 再生終了処理 // 次のファイルをサーチ N_Write = FindNext(rptr); // 次のファイルへ if((N_Write==0)&&(Record.attributes==ATTR_ARCHIVE)) pfile = FSfopen(Record.filename, "r"); else FindFirst("*.*", ATTR_ARCHIVE, rptr); str_filename = Record.filename; } //------------------------------------------------------------------------------ void __ISR(4,ipl5)T1Hander(void) // タイマ1割込 45.3μsec毎(22.05 KHz) { LATGbits.LATG15 = 0; delay_us(5); AD1CON1bits.SAMP =1; //サンプリング開始 while(!AD1CON1bits.DONE); //AD変換終了フラグがたつ(1になるまで)待つ temp1_ad = ADC1BUF0; //ADC1のAN1のバッファーからAD変換結果を読込む temp2_ad = temp1_ad*64 - 32768; //32768 = 64*1024 / 2; //無音基準レベル:32768( = unsigned int / 2) if(temp2_ad >= 32767) temp2_ad = 32767; //音声レベルクリップ if(temp2_ad <= -32768)temp2_ad = -32768; //送信優先: 未送信データがバッファに残っている場合は入力する音声データは無視する if(mode_tranceive == 0) //バッファ1 = 音声受信、バッファ0 = SD送信 { if(flag_buf1 == 0) //バッファ1が受信可能状態なら { LATDbits.LATD3 = 0; delay_us(2); data1_sound[count_buf1] = (short int)temp2_ad; //受信データをバッファ構造体1のdata_sound[ ]に保存 count_buf1++; LATDbits.LATD3 = 1; if(count_buf1 >= size_dataBlock) { count_buf1 = 0; flag_buf1 = 1; //バッファ1データ満杯 } } if((flag_buf1 == 1) && (flag_buf0 == 0))mode_tranceive = 1; //バッファー1が満杯で、かつSDへの送信データがなくなったら //バッファ1にまだ未送信音声データが残っていた場合は、音声データは受信しない } if(mode_tranceive == 1) //バッファ0 = 音声受信、バッファ1 = SD送信 { if(flag_buf0 == 0) //バッファ0が受信可能状態なら { data0_sound[count_buf0] = (short int)temp2_ad; //受信データをバッファ構造体2のdata_sound[ ]に保存 count_buf0++; delay_us(2); if(count_buf0 >= size_dataBlock) { count_buf0 = 0; flag_buf0 = 1; //バッファー0 データ満杯 } } if((flag_buf0 == 1) && (flag_buf1 == 0))mode_tranceive = 0; //バッファー0が満杯で、かつSDへの送信データがなくなったら } //バッファ2にまだ未送信音声データが残っていた場合は、音声データは受信しない // 終了のRB0入力検出 if(PORTBbits.RB0 == 1)Started_Osc = 0; if((Started_Osc == 0) && (PORTBbits.RB0 == 0)) { BtnCount++; //SWチャタリング対策 if(BtnCount >= 1200) //45.3μsec x 1200 = 54.4msec以上連続で押されていた場合--> タイマ1割り込み終了 { BtnCount = 0; if(count_block >= 10) //録音モード かつ 10ブロック以上書き込んでいるななら(チャタリング防止) { Stop_SDwriting = 1; //SDカード書込み終了 //1ブロック書込み後終了処理開始 //★ここですぐ終了処理を行わないこと!! ConfigIntTimer1(T1_INT_OFF | T1_INT_PRIOR_5); //タイマ1割込OFF、割り込みレベル5 } } } else BtnCount = 0; mT1ClearIntFlag(); //フラグクリア LATGbits.LATG15 = 1; } //--------------------------------------------------------------------------- void __ISR(26,ipl3)ChangeInt(void) //変化割り込み { if(PORTBbits.RB0 == 0) { delay_ms(60); //SWチャタリング対策 if(PORTBbits.RB0 == 0) { if(Mode_PlayRecord == 0) //再生モードの場合 → 録音開始 { //再生終了処理 MP3_XDCS_IO = 1; //VS1011E 音データ信号ラインOFF MP3_XCS_IO = 1; //VS1011E チップセレクト解除 FSfclose(pfile); // 現在のファイルを強制クローズ PlayEnd(); // 再生終了処理 Mode_PlayRecord = 1; //録音モードへ Record_First = 1; Stop_SDwriting = 0; //SDカードへの書き込み許可 count_block = 0; //SDカードに512バイト単位で書き込んだ回数をリセット count_buf0 = 0; //バッファ0データ数 count_buf1 = 0; //バッファ1データ数 flag_buf0 = 0; //音声データバッファ0の状態 flag_buf1 = 0; //音声データバッファ1の状態 // 0:音声データ受信可能状態 1:SDへ音声データ送信可能状態 mode_tranceive = 0; //送受信モード //0: バッファ1=音声タ受信、バッファ2=SD送信 //1: バッファ1=SD送信モード、バッファ2=音声受信 Started_Osc = 1; //タイマ1OSC 動作開始検出(開始1回目のみの検出)//RB0チャタリング対策 ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_5); //タイマ1割込ON、割り込みレベル5 ConfigIntCN(CHANGE_INT_OFF | CHANGE_INT_PRI_3); //状態変化割り込みOFF、優先度2 ConfigIntTimer4(T4_INT_OFF | T4_INT_PRIOR_1); } } } if(PORTBbits.RB1 == 0) SkipFile(); //CN3 スキップボタンがクリックされた場合 mCNClearIntFlag(); // 変化割り込みフラグクリア //IFS1bits.CNIF = 0; } //-------------------------------------------------------------------------------------------------------------------- void stop(GOL_MSG msg) { INTEnableInterrupts(); //全割り込み許可 while(1){ // 音量変更ボタンチェックと制御 if(ChgFlag){ // 音量変更ありか? ChgFlag = 0; SetVolume(Volume, Volume); // 音量設定 SetBassBoost(BASS, 15); // バスブースト設定 } if(GOLDraw()) // Draw GOL object { if(GOL_First == 0) //コードによるGDDXデザイナ諸元に係る追加の初期化実行 { GOL_First = 1; myGOLInit(); } TouchGetMsg(&msg); // Get message from touch screen GOLMsg(&msg); // Process message } } } //--------------------------------------------------------------------------------------------------------------------- void play(GOL_MSG msg) // 音楽データの出力 { if(pfile != 0) // 正常にオープンできたか? { // ファイルのEOFまで音声データ連続出力 do{ // 音量変更ボタンチェックと制御 if(ChgFlag){ // 音量変更ありか? ChgFlag = 0; SetVolume(Volume, Volume); // 音量設定 SetBassBoost(BASS, 15); // バスブースト設定 } // 音楽データの送信 INTDisableInterrupts(); //全割り込み禁止 // SPI処理中は割り込み禁止 if(Playing == 1) { MP3_XDCS_IO = 0; //#define MP3_XDCS_IO (LATAbits.LATA5) //#define MP3_XDCS_IO (LATBbits.LATB15) // 256バイト単位でファイルリード N_Write = FSfread(Buffer, 1, 256, pfile); for(i= 0; i< N_Write; i++){ // 読み出したバイト数だけ繰り返し SendData(Buffer[i]); // 音楽データ送信 } } INTEnableInterrupts(); //全割り込み許可 // 割り込み再許可 if(GOLDraw()) // Draw GOL object { if(GOL_First == 0) //コードによるGDDXデザイナ諸元に係る追加の初期化実行 { GOL_First = 1; myGOLInit(); } TouchGetMsg(&msg); // Get message from touch screen GOLMsg(&msg); // Process message } // DrawTouchDetect(); //スクリーン描画 & タッチ検出 }while(N_Write != 0); // ファイルのEOFまで継続 MP3_XDCS_IO = 1; FSfclose(pfile); // ファイルのクローズ PlayEnd(); pfile = FSfopen(str_filename, "r"); INTEnableInterrupts(); //全割り込み許可 } } void SelectItem(void) //リストボックスアイテムの選択 { short p_item; updateListBox = 0; //リストボックスタッチ検出リセット // 再生完了処理 FSfclose(pfile); // ファイルのクローズ PlayEnd(); LISTBOX *pLB = (LISTBOX*)GOLFindObject( LSB_1 ); //LSB_1:リストボックスの名前 p_item = LbGetFocusedItem (pLB); //フォーカスがあるアイテムの検出 switch(p_item) { case 0: str_filename = &File_Name[0][0]; LbSetFocusedItem(pLB,0); break; case 1: str_filename = &File_Name[1][0]; LbSetFocusedItem(pLB,1); break; case 2: str_filename = &File_Name[2][0]; LbSetFocusedItem(pLB,2); break; case 3: str_filename = &File_Name[3][0]; LbSetFocusedItem(pLB,3); break; case 4: str_filename = &File_Name[4][0]; LbSetFocusedItem(pLB,4); break; case 5: str_filename = &File_Name[5][0]; LbSetFocusedItem(pLB,5); break; case 6: str_filename = &File_Name[6][0]; LbSetFocusedItem(pLB,6); break; case 7: str_filename = &File_Name[7][0]; LbSetFocusedItem(pLB,7); break; case 8: str_filename = &File_Name[8][0]; LbSetFocusedItem(pLB,8); break; case 9: str_filename = &File_Name[9][0]; LbSetFocusedItem(pLB,9); break; case 10: str_filename = &File_Name[10][0]; LbSetFocusedItem(pLB,10); break; case 11: str_filename = &File_Name[11][0]; LbSetFocusedItem(pLB,11); break; case 12: str_filename = &File_Name[12][0]; LbSetFocusedItem(pLB,12); break; case 13: str_filename = &File_Name[13][0]; LbSetFocusedItem(pLB,13); break; case 14: str_filename = &File_Name[14][0]; LbSetFocusedItem(pLB,15); break; case 15: str_filename = &File_Name[15][0]; LbSetFocusedItem(pLB,15); break; case 16: str_filename = &File_Name[16][0]; LbSetFocusedItem(pLB,16); break; case 17: str_filename = &File_Name[17][0]; LbSetFocusedItem(pLB,17); break; case 18: str_filename = &File_Name[18][0]; LbSetFocusedItem(pLB,18); break; case 19: str_filename = &File_Name[19][0]; LbSetFocusedItem(pLB,19); break; case 20: str_filename = &File_Name[20][0]; LbSetFocusedItem(pLB,20); break; case 21: str_filename = &File_Name[21][0]; LbSetFocusedItem(pLB,21); break; case 22: str_filename = &File_Name[22][0]; LbSetFocusedItem(pLB,22); break; case 23: str_filename = &File_Name[23][0]; LbSetFocusedItem(pLB,23); break; case 24: str_filename = &File_Name[24][0]; LbSetFocusedItem(pLB,24); break; case 25: str_filename = &File_Name[25][0]; LbSetFocusedItem(pLB,25); break; case 26: str_filename = &File_Name[26][0]; LbSetFocusedItem(pLB,26); break; case 27: str_filename = &File_Name[27][0]; LbSetFocusedItem(pLB,27); break; case 28: str_filename = &File_Name[28][0]; LbSetFocusedItem(pLB,28); break; case 29: str_filename = &File_Name[29][0]; LbSetFocusedItem(pLB,29); break; default: break; } pfile = FSfopen(str_filename, "r"); } //------------------------------------------------------------------------------------------------------------------ int main(void) { INTEnableSystemMultiVectoredInt(); //ベクタ方式割り込みを許可する SYSTEMConfigPerformance(GetSystemClock()); //SYSTEMConfigPerformance(80000000);// システム最適化//キャッシュ・プリフェッチバッファ有効化 DDPCONbits.JTAGEN = 0; //I/OポートとしてRA0、RA1、RA4、RA5をつかう場合、電源投入後DDPCONレジスタのbit3を0に、設定する必要があり;ます。 //ADコンバータ初期設定 //音声入力 AD1PCFG = 0xFEFF; //b8=0以外は1 //Bポート:b8以外はデジタルピン TRISBbits.TRISB8 = 1; //RB8/AN8を入力ピンに設定 //AD1CON1レジスタの設定 AD1CON1bits.ON = 1; //A/Dコンバータモジュール有効 AD1CON1bits.SIDL = 0; //アイドルモード中もモジュール動作継続 AD1CON1bits.FORM2 = 0; //AD1CON1bits.FORM2-AD1CON1bits.FORM0のセットで出力データ形式指定 → 000:16ビット符号なし整数形式 AD1CON1bits.FORM1 = 0; //011:符号付固定16ビット小数 010:固定小数16ビット 001:符号付き整数16ビット 000:16ビット符号なし整数 AD1CON1bits.FORM0 = 0; //111:符号付32ビット固定小数 110:32ビット固定小数 101:符号付32ビット整数 100=32ビット符号なし整数 AD1CON1bits.SSRC2 = 1; //AD1CON1bits.SSRC2-AD1CON1bits.SSRC0 のセットでトリガーソースを指定 AD1CON1bits.SSRC1 = 1; //111: 内蔵カウンタでサンプリングを終了させ変換を開始する AD1CON1bits.SSRC0 = 1; //(参考)000: SAMPビットでサンプリングを終了し変換を開始する AD1CON1bits.CLRASAM = 0;//AD変換割り込み時の変換停止 0:次の変換値でオーバーライト AD1CON1bits.ASAM = 0; //SAMPビットのセットでサンプリングを開始する。(参考)1: 自動開始(前の変換終了後すぐサンプリングを開始する) AD1CON1bits.SAMP = 0; //サンプリング停止 //AD1CON2レジスタの設定 AD1CON2bits.VCFG2 = 0; //リファレンス選択//AD1CON2bits.VCFG2 - AD1CON2bits.VCFG0(VCFG<2:0>)の3ビットでセット AD1CON2bits.VCFG1 = 0; //000:リファレンス電圧 → Vdd -Vss AD1CON2bits.VCFG0 = 0; //(参考)001:リファレンス電圧 → 外部入力 - Vss 他 AD1CON2bits.OFFCAL = 0; //較正モード設定 0:サンプルホールドアンプSHAの入力はAD1CHSレジスタとAD1CSSLレジスタで制御される AD1CON2bits.CSCNA = 1; //マルチプレクサMUXAでのスキャン: する AD1CON2bits.SMPI3 = 0; //割り込みタイミング AD1CON2bits.SMPI3 - AD1CON2bits.SMPI0(SMPI<3:0>)の4ビットでセット AD1CON2bits.SMPI2 = 0; //0000: AD変換完了毎の割り込み発生(割り込み有効の場合) AD1CON2bits.SMPI1 = 0; //(参考)0011: 4サンプルのAD変換終了後 割り込み発生(割り込み有効の場合) AD1CON2bits.SMPI0 = 0; // AD1CON2bits.BUFM = 0; //バッファーを1個の16ワードバッファとする。 (参考)1: 2組の8ワードバッファーとする AD1CON2bits.ALTS = 0; //常にMUXAを入力マルチプレクサにする (参考)1: MUXA,MUXBを交互につかう //AD1CON3レジスタの設定 AD1CON3bits.ADRC = 0; //AD変換クロック源選択//0: PBCLK(Peripheral Bus Clock) (参考)1: A/D内臓RCクロック AD1CON3bits.SAMC4 = 1; //AD1CON3bits.SAMC4 - AD1CON3bits.SAMC0(SAMC<4:0>)の5ビットでセット AD1CON3bits.SAMC3 = 1; //アクイジションタイム(Tad(クロック周期)×N)設定(ホールドキャパシタ充電所要時間) AD1CON3bits.SAMC2 = 1; //1111: 31Tad AD1CON3bits.SAMC1 = 1; //(参考)0001: 1Tad 0010: 2Tad 0011: 3Tad ・・・・ AD1CON3bits.SAMC0 = 1; // AD1CON3bits.ADCS7 = 0; //AD変換時間の設定/AD1CON3bits.ADCS7 - AD1CON3bits.ADCS0(ADCS<7:0>)の8ビットでセット //AD変換完了フラグAD1CON1bits.DONEにより、AD変換完了を検知する場合は設定不要 AD1CON3bits.ADCS6 = 0; //AD変換完了までののクロック数選択ビット AD1CON3bits.ADCS5 = 0; //0000 0101: 1Tad = 6Tpb (Tpb: PBCLKの周期) AD1CON3bits.ADCS4 = 0; //(参考) 0000 0000: 1Tad = 2Tpb AD1CON3bits.ADCS3 = 0; // 0000 0001: 1Tad = 3Tpb AD1CON3bits.ADCS2 = 1; // 0000 0010: 1Tad = 4Tpb AD1CON3bits.ADCS1 = 0; // ・・・・ AD1CON3bits.ADCS0 = 1; // 1111 1111: 1Tad = 512Tpb //AD1CHSレジスタの設定 //SHAの+端子とー端子への接続(ポート)設定 AD1CHSbits.CH0NB = 0; //マルチプレクサMUXB用負側入力選択ビット: VR- (参考)1: AN1 AD1CHSbits.CH0SB3 = 0; //AD1CHSbits.CH0SB3 - AD1CHSBbits.CH0SB0(<CH0SB<3:0>)の4ビットでセット AD1CHSbits.CH0SB2 = 0; //マルチプレクサMUXBの正側入力選択 AD1CHSbits.CH0SB1 = 0; //0000: AN0 AD1CHSbits.CH0SB0 = 0; //(参考)0001: AN1 0011 AN2 .... 1111: AN15 AD1CHSbits.CH0NA = 0; //マルチプレクサMUXA用負側入力選択ビット: VR- (参考)1: AN1 AD1CHSbits.CH0SA3 = 0; //AD1CHSbits.CH0SA3 - AD1CHSbits.CH0SA0(<CH0SA<3:0>)の4ビットでセット AD1CHSbits.CH0SA2 = 0; //マルチプレクサMUXAの正側入力選択 AD1CHSbits.CH0SA1 = 0; //0000: AN0 AD1CHSbits.CH0SA0 = 0; //(参考)0001: AN1 0011 AN2 .... 1111: AN15 //AD1PCFGレジスタの設定 // ポートのアナログorデジタル設定 //★デバイスリセットでは全ビット0となるためデフォルトではアナログ入力となるのでデジタルで使う多重ピンは、コンフィグレーションでデジタル設定が必要!! AD1PCFGbits.PCFG15 = 1;//RB15/AN15アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG14 = 1;//RB14/AN14アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG13 = 1;//RB13/AN13アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG12 = 1;//RB12/AN12アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG11 = 1;//RB11/AN11アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG10 = 1;//RB10/AN10アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG9 = 1;//RB9/AN9アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG8 = 0;//RB8/AN8アナログ入力orデジタル入力選択: アナログ //★AN8から音声を入力する AD1PCFGbits.PCFG7 = 1;//RB7/AN7アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG6 = 1;//RB6/AN6アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG5 = 1;//RB5/AN5アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG4 = 1;//RB4/AN4アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG3 = 1;//RB3/AN3アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG2 = 1;//RB2/AN2アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG1 = 1;//RB1/AN1アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG0 = 1;//RB0/AN0アナログ入力orデジタル入力選択: デジタル //AD1CSSLレジスタの設定 //読み込むチャンネル(入力端子)をセットする AD1CSSLbits.CSSL15 = 0; //AN15をMUXAでスキャンしない AD1CSSLbits.CSSL14 = 0; //AN15をMUXAでスキャンしない AD1CSSLbits.CSSL13 = 0; //AN13をMUXAでスキャンしない AD1CSSLbits.CSSL12 = 0; //AN12をMUXAでスキャンしない AD1CSSLbits.CSSL11 = 0; //AN11をMUXAでスキャンしない AD1CSSLbits.CSSL10 = 0; //AN10をMUXAでスキャンしない AD1CSSLbits.CSSL9 = 0; //AN9をMUXAでスキャンしない AD1CSSLbits.CSSL8 = 1; //AN8をMUXAでスキャンする //★使用するAN8のチャンネルだけ読み込む AD1CSSLbits.CSSL7 = 0; //AN7をMUXAでスキャンしない AD1CSSLbits.CSSL6 = 0; //AN6をMUXAでスキャンしない AD1CSSLbits.CSSL5 = 0; //AN5をMUXAでスキャンしない AD1CSSLbits.CSSL4 = 0; //AN4をMUXAでスキャンしない AD1CSSLbits.CSSL3 = 0; //AN3をMUXAでスキャンしない AD1CSSLbits.CSSL2 = 0; //AN2をMUXAでスキャンしない AD1CSSLbits.CSSL1 = 0; //AN1をMUXAでスキャンしない AD1CSSLbits.CSSL0 = 0; //AN0をMUXAでスキャンしない TRISBbits.TRISB15 = 0; //キャラクタ液晶ポート設定 TRISBbits.TRISB14 = 0; //キャラクタ液晶ポート設定 TRISBbits.TRISB13 = 0; //キャラクタ液晶ポート設定 TRISBbits.TRISB12 = 0; //キャラクタ液晶ポート設定 TRISAbits.TRISA9 = 0; //キャラクタ液晶ポート設定 TRISAbits.TRISA10 = 0; //キャラクタ液晶ポート設定 TRISDbits.TRISD2 = 0; //RD2: out TRISDbits.TRISD3 = 0; //RD3: out TRISGbits.TRISG15 = 0; LATDbits.LATD2 = 1; LATDbits.LATD3 = 1; LATGbits.LATG15 = 1; /// インターバルタイマ1 周期 45.3μsec (音データサンプリング周期) OpenTimer1( T1_ON | // タイマ1 イネーブル //T1_OFF → タイマ1 ディセーブル T1_SOURCE_INT | //クロックソース:インターナル //T1_SOURCE_EXT → 外部発振器 T1_PS_1_1, //プリスケール 1/256 //1/1、1/2、1/4、1/8、1/16、1/32、1/64、1/256 3624 //PRx値: T0[μsec] = 1000x1000/80000000x3624 = 1/80x3624 = 45.3μsec ); // VS1011eの初期化 VS1011_Init(); Volume = 0x08; // 音量の初期設定 SetVolume(Volume, Volume); BASS = 0; // バスブーストの初期設定 SetBassBoost(BASS,15); // VS1011のデバッグ時テスト用のコマンド // VS1011_SineTest(); // 正弦波出力テスト lcd_init(); // LCD初期化 lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF //// SDカードの実装とフォーマット済をチェック while(!FSInit()); //SDカードの実装とフォーマット済をチェック // 最初のファイルのサーチ(ルートだけにMP3ファイルがあることが前提) myResult = FindFirst("*.*", ATTR_ARCHIVE, rptr); if(myResult == 0) { N_Item = 0; pfile = FSfopen(Record.filename, "r"); // ファイルのオープン sprintf(&File_Name[0][0],"%s",Record.filename); //ファイル名 //空白必須 } while(1) { FSfclose(pfile); // ファイルのクローズ myResult = FindNext(rptr); // 次のファイルへ if((myResult == 0)&&(Record.attributes == ATTR_ARCHIVE)) { N_Item++; pfile = FSfopen(Record.filename, "r"); sprintf(&File_Name[N_Item][0],"%s",Record.filename); } else break; //ルートディレクトリのファイルをすべて検出した場合 } mCNOpen(CN_ON, //状態変化モジュール ON CN2_ENABLE | //CN2 Enable CN3_ENABLE , //CN3 Enable CN2_PULLUP_ENABLE | //CN2 プルアップ抵抗設定 CN3_PULLUP_ENABLE //CN3 プルアップ抵抗設定 ); ConfigIntCN(CHANGE_INT_ON | CHANGE_INT_PRI_3); //状態変化割り込みON、優先度2 DisplayResetDisable(); //Sets RST high DisplayResetConfig(); //Sets the pin to output DelayMs(3000); //Wait 3000 ms at startup SetColor(BLACK); ClearDevice(); GOL_MSG msg; // GOL message structure to interact with GOL GOLInit(); // Initialize graphics library and create default style scheme for GOL TouchHardwareInit(); //タッチパネル初期化 TickInit(); //タイマ4 初期化 GDDDemoCreateFirstScreen(); while(1) { switch(Mode_PlayRecord) { case 0: //再生 または停止モード play(msg); break; case 1: //録音モード if(Record_First == 1) //録音開始の1回だけのルーチン { Record_First = 0; Recording_Voice = 1; pfile = FSfopen("VOICE.WAV","w"); //ファイル上書き込みモードでオープン 但しファイルがなければ新規ファイル作成 if(pfile == NULL)return; //ファイルオープン失敗の場合 lcd_clear(); // 全消去 lcd_cmd(0x80); //1行目の先頭へ sprintf(Buf,"VOICE.WAV"); //ファイル名 //空白必須 lcd_str(Buf); // 開始メッセージ1行目表示 lcd_cmd(0xC0); //2行目の先頭へ sprintf(Buf,"On recording"); //タッチY座標表示 lcd_str(Buf); // 開始メッセージ2行目表示 ptrWH = &mywaveheader; //構造体にmywaveheaderの先頭アドレス設定 adr_SD = 0; FSfseek(pfile,0,SEEK_SET); //ファイルの先頭にファイルポインタの位置を移動 N_Write = FSfwrite((const void*)ptrWH,sizeof(struct myWaveHeader),1,pfile);//ファイルにヘッダー情報書き込み if(N_Write != 1)Reset(); adr_SD = 0x2C; //ファイルの先頭から0x2C(44)バイト(音声データ書き込み開始オフセット)のところにに N_Write = FSfseek(pfile,adr_SD,SEEK_SET);//ファイルポインタの位置を移動 //戻り値: 0:成功 1:失敗 // Position = FSftell(pfile);//ファイルポインタの位置を確認 } if(Recording_Voice == 1) { if(mode_tranceive == 0) //バッファ0=SD送信、バッファ1=音声受信モード { if(flag_buf0 == 1) //バッファ0がSDへ送信可能状態の場合・バッファ1は音声受信可能状態 { N_Write = FSfwrite((const void*)data0_sound,sizeof(short int),size_dataBlock,pfile);//SDカードにデータ書き込み if(N_Write == 512)count_block++; else Reset(); flag_buf0 = 0; //→ バッファ2送信完了、受信可能状態 } } if(mode_tranceive == 1) //バッファ1 = SDへ送信可、バッファ0=音声受信モード { if(flag_buf1 == 1) //バッファ1がSDへ送信可能状態の場合・バッファ2は音声受信可能状態 { N_Write = FSfwrite((const void*)data1_sound,sizeof(short int),size_dataBlock,pfile);//SDカードにデータ書き込み if(N_Write == 512)count_block++; else Reset(); flag_buf1 = 0; //→ バッファ1送信完了、受信可能状態 } } if(Stop_SDwriting == 1) // { delay_ms(200); Recording_Voice = 0; mywaveheader.size_data = count_block * 1024 ; //[バイト] mywaveheader.size_file = count_block * 1024 + sizeof mywaveheader - 8; //[バイト] delay_ms(100); N_Write = FSfseek(pfile,0,SEEK_SET); //ファイルの先頭にファイルポインタの位置を移動 N_Write = FSfwrite((const void*)ptrWH,sizeof(struct myWaveHeader),1,pfile); //ファイルにヘッダー情報書き込み delay_ms(100); N_Write = FSfclose(pfile); // ファイルを閉じる while(!FSInit()); //SDカードの実装とフォーマット済をチェック ConfigIntCN(CHANGE_INT_ON | CHANGE_INT_PRI_3); //状態変化割り込みON、優先度3 ConfigIntTimer4(T4_INT_ON | T4_INT_PRIOR_1); Mode_PlayRecord = 0; //音楽再生モードへ // delay_ms(1000); pfile = FSfopen("VOICE.WAV", "r"); // ファイルのオープン LISTBOX *pLB = (LISTBOX*)GOLFindObject( LSB_1 ); //get ListBox object pLB->hdr.state = LB_DRAW | LB_CENTER_ALIGN | LB_SINGLE_SEL; // LB_SINGLE_SEL:1つのアイテムを選択 LbDelItemsList(pLB); //すべてのアイテムを消去//カレントアイテムをなしにする//addアイテムでitemを先頭にもってくる for(ix = 0; ix <= 9; ix++) //表示ファイル数=10 // for(ix = 0; ix <= N_Item; ix++) { pAddedItem = LbAddItem( pLB, NULL, &File_Name[ix][0] , NULL, 0, 0); //ファイル名をリストに順次追加 if(ix == 0) { pAddedItem0 = pAddedItem; LbSetSel(pLB, pAddedItem0); //アイテム0を選択 LbSetFocusedItem(pLB,0); //アイテム0にフォーカスをセット str_filename = &File_Name[0][0]; pfile = FSfopen(str_filename, "r"); } } SetState( pLB, LB_DRAW); } } break; default: break; } //switch(Mode)のend } //while(1)のend } //main(void)のend //------------------------------------------------------------------------------ WORD GOLMsgCallback(WORD objMsg, OBJ_HEADER *pObj, GOL_MSG *pMsg) { WORD objectID; objectID = GetObjID(pObj); GDDDemoGOLMsgCallback(objMsg, pObj, pMsg); // Add additional code here... if(objectID == BTN_1){ /* if(objMsg == BTN_MSG_PRESSED){ if(Mode_Btn1 == 0)Mode_Btn1 = 1; else Mode_Btn1 = 0; Change_Btn1 = 1; } */ } return (1); } //------------------------------------------------------------------------------ WORD GOLDrawCallback(void) { GDDDemoGOLDrawCallback(); // Add additional code here... if(Change_Btn1 == 1) { /* BUTTON *pBTN_1; if(Mode_Btn1 == 1) { LATGbits.LATG15 = 1; pBTN_1->hdr.pGolScheme->Color0 = YELLOW; //ボタン表面を黄色へ } else { LATGbits.LATG15 = 0; pBTN_1->hdr.pGolScheme->Color0 = BLUE; //ボタン表面を青色 } Change_Btn1 = 0; */ } if(updateListBox == 1)SelectItem(); return (1); } //------------------------------------------------------------------------------ void __ISR(_TIMER_4_VECTOR, ipl1) _T4Interrupt(void) //タイマ4割り込み //100msec毎 { // LATGbits.LATG15 = 0; //割り込み時間(実測):3msec tick++; TMR4 = 0; mT4ClearIntFlag(); // Clear flag TouchDetectPosition(); SLIDER *pSlider = (SLIDER*)GOLFindObject(SLD_1); //スライダのオブジェクト検出 PosSld = SldGetPos(pSlider); //スライダーのツマミ位置検出 ChgFlag = 1; Volume = (int)(-0.64 * PosSld + 64); if(Volume >= 254)Volume = 254; //最小音量 if(Volume <= 0)Volume = 0; //最大音量 lcd_clear(); // 全消去 lcd_cmd(0x80); //1行目の先頭へ sprintf(Buf,"%s ",str_filename); //ファイル名 //空白必須 lcd_str(Buf); // 開始メッセージ1行目表示 lcd_cmd(0xC0); //2行目の先頭へ sprintf(Buf,"X=%d Y=%d V=%d",TouchGetX(),TouchGetY(),PosSld); //タッチY座標表示 lcd_str(Buf); // 開始メッセージ2行目表示 if(Press_BTN_1 == 1)LATGbits.LATG15 = 0; else LATGbits.LATG15 = 1; if(Press_BTN_1 == 1)Count_BTN_1++; else Count_BTN_1 = 0; if(Count_BTN_1 == 2) { if(Playing == 0) { Playing =1; //演奏 LATDbits.LATD2 = 0; } else { Playing = 0; //演奏中断 LATDbits.LATD2 = 1; } } if(Count_BTN_1 >= 4)Count_BTN_1 = 4; // LATGbits.LATG15 = 1; } //--------------------------------------------------------------------------------- #define SAMPLE_PERIOD 500 // us #define TICK_PERIOD (GetPeripheralClock() * SAMPLE_PERIOD) / 4000000 //TICK_PERIOD = 80000000 * 500 / 4000000 = 80* 500 / 4 = 20*500 = 10000 void TickInit(void) //タイマ4初期化 { OpenTimer4(T4_ON | T4_PS_1_256, 31249); //1000/80000000*256*31249 =99.9968 msec // OpenTimer4(T4_ON | T4_PS_1_8, 10000); //2msec // OpenTimer4(T4_ON | T4_PS_1_8, TICK_PERIOD); //実測値:35μsec //オーバーフローエラー発生 ConfigIntTimer4(T4_INT_ON | T4_INT_PRIOR_1); } //----------------------------------------------------------------------------------------------------------------- //HardwareProfile.h //タッチパネル式WAV録音機能付MP3プレーヤー #ifndef __HARDWARE_PROFILE_H #define __HARDWARE_PROFILE_H #include "Compiler.h" #define GetSystemClock() (80000000ul) //システムクロック設定 #define GetPeripheralClock() (GetSystemClock() / (1 << OSCCONbits.PBDIV)) //ペリフェラルクロック設定 #define GetInstructionClock() (GetSystemClock()) #define USE_16BIT_PMP //液晶表示信号伝送方式:8080 16ビットパラレル信号 #define EXPLORER_16 //マイクロチップ デモボードEexplore 16 インターフェース #define GFX_PICTAIL_V3 ////マイクロチップ デモボードEexplore 16 インターフェース のバージョン #define USE_SST25VF016 //フラッシュメモリSST25VF016を使用 //★使用しなくてもコンパイル上必須 #define GFX_USE_DISPLAY_CONTROLLER_SSD1963 //LCDコントローラはSSD1963使用 #define GFX_USE_DISPLAY_PANEL_INT035TFT //液晶パネルは DisplayTech Ltd のINT035TFTを使用 #define USE_GFX_PMP //パラレルマスターポートモジュール PMP #define USE_SD_INTERFACE_WITH_SPI //SDカードインターフェース:SPI //SD カード選択・検出 //CS:チップセレクト // Description: SD-SPI Chip Select Output bit #define SD_CS LATDbits.LATD14 //LATCbits.LATC3 #define SD_CS_TRIS TRISDbits.TRISD14 // TRISCbits.TRISC3 //CD:カードディテクト // Description: SD-SPI Card Detect Input bit #define SD_CD PORTFbits.RF12 // PORTDbits.RD8 #define SD_CD_TRIS TRISFbits.TRISF12 // TRISDbits.TRISD8 //WE:ライトイネーブル Description: SD-SPI Write Protect Check Input bit #define SD_WE PORTAbits.RA1 #define SD_WE_TRIS TRISAbits.TRISA1 //SPIコンフィギュレーション //SPI Configuration #define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) #define SPI_START_CFG_2 (SPI_ENABLE) #define SPI_FREQUENCY (10000000) //SPI周波数 //Define the SPI frequency // #define SPI_FREQUENCY (20000000) //SPI周波数 //Define the SPI frequency //チャンネル4: #define SPICON1 SPI4CON //制御レジスタ #define SPISTAT SPI4STAT //SPIステータスレジスタ status register #define SPIBUF SPI4BUF //SPIバッファレジスタ #define SPISTAT_RBF SPI4STATbits.SPIRBF //受信バッファ満杯ビット// The receive buffer full bit in the SPI status register #define SPICON1bits SPI4CONbits //ビット単位の定義(制御レジスタ)The bitwise define for the SPI control register (i.e. _____bits) #define SPISTATbits SPI4STATbits //ビット単位の定義(ステータスレジスタ) //The bitwise define for the SPI status register (i.e. _____bits) #define SPIENABLE SPI4CONbits.ON //SPIモジュール イネーブルビット //The enable bit for the SPI module #define SPIBRG SPI4BRG //ボーレートジェネレータ//The definition for the SPI baud rate generator register (PIC32) //SCK,SDI,SDOピンアサイン //Tris pins for SCK/SDI/SDO lines #define SPICLOCK TRISFbits.TRISF13 //TRISGbits.TRISG6 //SCK #define SPIIN TRISFbits.TRISF4 //PICのSDI4 // TRISGbits.TRISG7 //PICのSDI2 #define SPIOUT TRISFbits.TRISF5 //PICのSDO4 // TRISGbits.TRISG8 //SDO //SPIライブラリ関数 //library functions // #define putcSPI putcSPI4 //putcSPI2 // #define getcSPI getcSPI4 //getcSPI2 // #define OpenSPI(config1, config2) OpenSPI4(config1, config2) //OpenSPI2(config1, config2) // ----------------------------------- // For RGB GLASS // ----------------------------------- #if defined (GFX_USE_DISPLAY_PANEL_INT035TFT) #define DISP_ORIENTATION 0 //液晶画面の回転なし //(参考)90度回転の場合: 90 #define DISP_HOR_RESOLUTION 320 //水平解像度[dot] #define DISP_VER_RESOLUTION 240 //垂直解像度[dot] #define MAX_JUMP (10*4096/DISP_HOR_RESOLUTION) //ノイズ除去スレッシュホールドレベル//Noise rejection threshold #endif /********************************************************************* * PARALLEL MASTER PORT INTERFACE TIMING *********************************************************************/ #if defined (GFX_USE_DISPLAY_CONTROLLER_SSD1963) #define PMP_DATA_SETUP_TIME (50) //データセットアップ時間[μsec]//データシートより #define PMP_DATA_WAIT_TIME (82) //データウェィト時間[μsec] //データシートより #define PMP_DATA_HOLD_TIME (30)//データホールド時間[μsec] //データシートより #endif // Depending on the display panel used, the backlight control may be // different. This portion sets up the correct backlight level to #if defined (GFX_USE_DISPLAY_PANEL_INT035TFT) #define BACKLIGHT_ENABLE_LEVEL 1 #define BACKLIGHT_DISABLE_LEVEL 0 #endif //液晶表示制御関係 //インテル8080 16ビットパラレル 制御信号ポート設定 //(参考)RD,WRのポート設定はPMPモジュールの初期設定で実施 //RESETピンの定義 // Definitions for reset pin #define DisplayResetConfig() TRISCbits.TRISC1 = 0; //RC1: out //TRISCCLR = _TRISC_TRISC1_MASK #define DisplayResetEnable() LATCbits.LATC1 = 0; //LATCCLR = _LATC_LATC1_MASK #define DisplayResetDisable() LATCbits.LATC1 = 1; //LATCSET = _LATC_LATC1_MASK // //RSピンの定義 Definitions for RS pin #define DisplayCmdDataConfig() TRISCbits.TRISC2 = 0; //RC2: out //TRISCCLR = _TRISC_TRISC2_MASK // #define DisplaySetCommand() LATCbits.LATC2 = 0; //LATCCLR = _LATC_LATC2_MASK #define DisplaySetData() LATCbits.LATC2 = 1; //LATCSET = _LATC_LATC2_MASK //CSピンの定義 Definitions for CS pin #define DisplayConfig() TRISDbits.TRISD10 = 0; //RD10: out //TRISDCLR = _TRISD_TRISD10_MASK #define DisplayEnable() LATDbits.LATD10 = 0; //LATDCLR = _LATD_LATD10_MASK #define DisplayDisable() LATDbits.LATD10 = 1; //LATDSET = _LATD_LATD10_MASK // Definitions for backlight control pin //使用していないが未定義だとコンパイルエラー発生 #define DisplayBacklightConfig() #define DisplayBacklightOn() #define DisplayBacklightOff() // Definitions for FLASH CS pin //使用していないが未定義だとコンパイルエラー発生 #define DisplayFlashConfig() #define DisplayFlashEnable() #define DisplayFlashDisable() // Definitions for POWER ON pin //使用していないが未定義だとコンパイルエラー発生 #define DisplayPowerConfig() #define DisplayPowerOn() #define DisplayPowerOff() //タッチスクリーンMAX11802関係 //ポートの定義 //TP_DIN #define TPMOSIConfig() (TRISGbits.TRISG12 = 0) //RG12: out #define TPMOSIHigh() (LATGbits.LATG12 = 1) #define TPMOSILow() (LATGbits.LATG12 = 0) //TP_DOUT #define TPMISOConfig() (TRISAbits.TRISA7 = 1) //RA7: in #define TPMISOHigh() (LATAbits.LATA7 = 1) #define TPMISOLow() (LATAbits.LATA7 = 0) #define TPMISORead() (PORTAbits.RA7) //TP_CLK #define TPSCLConfig() (TRISGbits.TRISG14 = 0) //RG14: out #define TPSCLHigh() (LATGbits.LATG14 = 1) #define TPSCLLow() (LATGbits.LATG14 = 0) //TP_CS #define TPCSConfig() (TRISAbits.TRISA6 = 0) //RA6: out #define TPCSHigh() (LATAbits.LATA6 = 1) #define TPCSLow() (LATAbits.LATA6 = 0) //TP_TIRQ //液晶にタッチがあるとTP_TIRQピンからワンショットバルスが発生する #define TPIRQConfig() (LATGbits.LATG13 = 1) //RG13: in #define TPIRQRead() (PORTGbits.RG13) //入出力ビット定義・初期化関数 #define InitBitBangedIO(){ \ TPMOSIHigh(); \ TPMOSIConfig(); \ TPMISOConfig(); \ TPSCLLow(); \ TPSCLConfig(); \ TPCSHigh(); \ TPCSConfig(); \ } //★以下の #if define (USE_SST2VF016) ? #end if の部分は、素子の実装有無にかかわらずコンパイル上必須である。 // ADDRESS_RESISTIVE_TOUCH_VERSION、SST25_CS_LAT等が TouchScreen.c、SST25VF016.c 等で未定義のコンパイルエラーとなる //SST25VFD016: マイクロチップ製 フラッシュメモリ SPIインターフェース、メモリ容量:16Mbit /********************************************************************* * HARDWARE PROFILE FOR THE SPI FLASH MEMORY *********************************************************************/ #if defined (USE_SST25VF016) #define SST25_SPI_CHANNEL 2 #define SPI_CHANNEL_2_ENABLE #define SST25_CS_TRIS TRISGbits.TRISG9 #define SST25_CS_LAT LATGbits.LATG9 #define SST25_SCK_TRIS TRISGbits.TRISG6 #define SST25_SDO_TRIS TRISGbits.TRISG8 #define SST25_SDI_TRIS TRISGbits.TRISG7 #define SST25_SDI_ANS ANSGbits.ANSG7 #define SPIFlashConfigurePins() { \ SST25_SDO_ANS = ANSEL_DIGITAL; \ SST25_SDI_ANS = ANSEL_DIGITAL; \ SST25_CS_LAT = 1; \ SST25_CS_TRIS = 0; \ SST25_SCK_TRIS = 0; \ SST25_SDO_TRIS = 0; \ SST25_SDI_TRIS = 1; \ } // Addresses for calibration and version values in SPI Flash on Graphics PICtail 3 & PIC24FJ256DA210 Development Board. #define ADDRESS_RESISTIVE_TOUCH_VERSION (unsigned long)0xFFFFFFFE #define ADDRESS_RESISTIVE_TOUCH_ULX (unsigned long)0xFFFFFFFC #define ADDRESS_RESISTIVE_TOUCH_ULY (unsigned long)0xFFFFFFFA #define ADDRESS_RESISTIVE_TOUCH_URX (unsigned long)0xFFFFFFF8 #define ADDRESS_RESISTIVE_TOUCH_URY (unsigned long)0xFFFFFFF6 #define ADDRESS_RESISTIVE_TOUCH_LLX (unsigned long)0xFFFFFFF4 #define ADDRESS_RESISTIVE_TOUCH_LLY (unsigned long)0xFFFFFFF2 #define ADDRESS_RESISTIVE_TOUCH_LRX (unsigned long)0xFFFFFFF0 #define ADDRESS_RESISTIVE_TOUCH_LRY (unsigned long)0xFFFFFFEE // define the functions to call for the non-volatile memory // check out touch screen module for definitions of the following function pointers // used: NVM_READ_FUNC, NVM_WRITE_FUNC & NVM_SECTORERASE_FUNC #define NVMSectorErase ((NVM_SECTORERASE_FUNC)&SST25SectorErase) #define NVMWrite ((NVM_WRITE_FUNC)&SST25WriteWord) #define NVMRead ((NVM_READ_FUNC)&SST25ReadWord) #endif // #if defined (USE_SST25VF016) #endif // __HARDWARE_PROFILE_H //---------------------------------------------------------------------------------------------------------------------- /********************************************************************* * VS1011E用ヘッダファイル * このライブラリは後閑哲也さんが設計されたものです。 * SPIチャンネルは PIC24FJ64GA002のSPIチャンネル2から * PIC32MX795F512Lのチャンネル3に変更しています。 ********************************************************************/ #include "GenericTypeDefs.h" //Delay関数用クロック周波数定義 //#define CLOCK 16 // MHz // ポートの定義 #define MP3_DREQ_TRIS (TRISAbits.TRISA15) //(TRISBbits.TRISB14) // Data Request #define MP3_DREQ_IO (PORTAbits.RA15) //(PORTBbits.RB14) #define MP3_XRESET_TRIS (TRISDbits.TRISD11) //(TRISAbits.TRISA0) // Reset, active low #define MP3_XRESET_IO (LATDbits.LATD11) //(LATAbits.LATA0) #define MP3_XDCS_TRIS (TRISAbits.TRISA5) //(TRISBbits.TRISB15) // Data Chip Select #define MP3_XDCS_IO (LATAbits.LATA5) //(LATBbits.LATB15) #define MP3_XCS_TRIS (TRISAbits.TRISA14) //(TRISBbits.TRISB13) // Control Chip Select #define MP3_XCS_IO (LATAbits.LATA14) //(LATBbits.LATB13) //SPI3を使用 // SPIはSPI2を使用 #define MP3_SCK_TRIS (TRISDbits.TRISD15) //SDK3/RD15 (TRISBbits.TRISB12) //VS1011e #define MP3_SDI_TRIS (TRISFbits.TRISF2) //SDI3/RF2 (TRISBbits.TRISB10) #define MP3_SDO_TRIS (TRISFbits.TRISF8) //SDO3/RF8 (TRISBbits.TRISB11) #define MP3_SPI_IF (IFS0bits.SPI3RXIF) //RX書込み完了フラグ //(IFS2bits.SPI2IF)/Flag Status bit 1:interrupt occured 0:interrupt not occured #define MP3_SSPBUF (SPI3BUF) // (SPI2BUF) #define MP3_SPICON1 (SPI3CON) // (SPI2CON1) //#define MP3_SPICON1bits (SPI3CONbits) //(SPI2CON1bits) //#define MP3_SPICON2 (SPI3CON) //SPI2CON2 //#define MP3_SPISTAT (SPI3STAT) //(SPI2STAT) //#define MP3_SPISTATbits (SPI3STATbits) //(SPI2STATbits) /* 関数プロトタイピング */ BYTE WriteSPI(BYTE output); void Command(BYTE RegAdrs, BYTE UpData, BYTE LowData); void SendData(BYTE Data); //void delay_ms(int msec); void VS1011_Init(void); void VS1011_SineTest(void); void SetVolume(BYTE right, BYTE left); void SetBassBoost(BYTE bass, BYTE gfreq); void PlayEnd(void); //----------------------------------------------------------------------------------------------------------------------------- /***************************************************** * VS1011E 制御ライブラリ * //このライブラリは後閑哲也さんがPIC24FJ64GA002のSPIチャンネル2用に設計されたライブラリを * //PIC32MX795F512Lのチャンネル3用に変更したものです。 ******************************************************/ #include "VS1011.h" #include <p32xxxx.h> //#include <p24FJ64GA002.h> /************************************ * SPI Read after Write 基本関数 ************************************/ BYTE WriteSPI(BYTE output){ MP3_SPI_IF = 0; //受信完了フラグクリア // 割り込みフラグクリア MP3_SSPBUF = output; // SPI出力 while(!MP3_SPI_IF); //受信完了割込みフラグ待ち // 入力待ち return MP3_SSPBUF; // // 入力データ戻り値 } /************************************ * VS1011用コマンド出力関数 ************************************/ void Command(BYTE RegAdrs, BYTE UpData, BYTE LowData){ MP3_XDCS_IO = 1; // データモード解除 while(!MP3_DREQ_IO); // レディー待ち MP3_XCS_IO = 0; // コマンドモード設定 WriteSPI(0x02); // 書き込み動作指定 WriteSPI(RegAdrs); // レジスタアドレス出力 WriteSPI(UpData); // 上位バイト出力 WriteSPI(LowData); // 下位バイト出力 MP3_XCS_IO = 1; // コマンドモード解除 } /************************************ * VS1011用コマンド出力関数(確認付き) ************************************/ void CmdCheck(BYTE RegAdrs, BYTE UpData, BYTE LowData){ BYTE b1,b2; do{ MP3_XDCS_IO = 1; // データモード解除 while(!MP3_DREQ_IO); // レディー待ち MP3_XCS_IO = 0; // コマンドモード設定 WriteSPI(0x02); // 書き込み動作指定 WriteSPI(RegAdrs); // レジスタアドレス出力 WriteSPI(UpData); // 上位バイト出力 WriteSPI(LowData); // 下位バイト出力 MP3_XCS_IO = 1; // コマンドモード解除 while(!MP3_DREQ_IO); // レディー待ち MP3_XCS_IO = 0; // 読み込み確認 WriteSPI(0x03); // 読み込み動作 WriteSPI(RegAdrs); // レジスタアドレス指定 b1 = WriteSPI(0xFF); // return UpData b2 = WriteSPI(0xFF); // return LowData MP3_XCS_IO = 1; }while((b1 != UpData) || (b2 != LowData)); } /************************************ * VS1011用データ出力関数 ************************************/ void SendData(BYTE Data){ while(!MP3_DREQ_IO); // レディー待ち WriteSPI(Data); } /*********************************************** * 音量レベル設定関数 * vRight = 右チャネル用音量 * vLeft = 左チャネル用音量 * いすれも 0x00=Max 0dB 0.5dBステップで下がる ************************************************/ void SetVolume(BYTE vRight, BYTE vLeft){ Command(0x0B, vRight, vLeft); } /********************************************** * 低音ブースト設定制御関数 * bass: 低音ゲイン レンジは0dBから15dBの範囲 * gfreq: 低音ブースト周波数設定 10Hzステップ 0?15の範囲 ***********************************************/ void SetBassBoost(BYTE bass, BYTE gfreq) { BYTE temp1 = 0; /* 設定範囲の制限 */ if(bass > 15) bass = 15; if(gfreq > 15) gfreq = 15; /* 8ビットに合成 */ temp1 = gfreq; temp1 |= (bass << 4); Command(0x02, 0xFF, temp1); // BASS return; } /********************************************* * 再生終了処理関数 * *********************************************/ void PlayEnd(void){ int i; /* 再生バッファクリアのため2048バイト送信 */ MP3_XDCS_IO = 0; // XDCSオン for(i=0; i<2048; i++) SendData(0); // 0のデータ連続送信 MP3_XDCS_IO = 1; // XDCSオフ /*** ソフトウェアリセットで完了 **/ Command(0x00, 0x08, 0x24); // SM_RESET送信 while(!MP3_DREQ_IO); // コマンド完了待ち } /******************************************** * VS1011 初期化関数 * VS1011転送モード、SDIテストモード に設定 * VS1011と正常に通信できないと永久待ちとなる *********************************************/ void VS1011_Init(void) { unsigned int val; // VS1011用ポートの初期設定 MP3_XDCS_IO = 1; // DCSをHigh MP3_XCS_IO = 1; // XCSをHigh MP3_XRESET_IO = 0; // XRESETをLow MP3_XRESET_TRIS = 0; // 出力TRIS有効化 MP3_DREQ_TRIS = 1; // DREQ入力モードに MP3_XDCS_TRIS = 0; // XDCS出力///////// MP3_XCS_TRIS = 0; // XCS出力 MP3_SDI_TRIS = 1; // SDI2入力モード MP3_SDO_TRIS = 0; // SDO2出力モード MP3_SCK_TRIS = 0; // SCK2出力モード // SPI3の初期設定 MP3_SPICON1 = 0x8120; //0b1000 0001 0010 0000 // 8ビット転送モード,CKP = 0,CLK=Fosc/4 (4MHz) // 中央でサンプル(SMP=0) 立上りエッジで送信(CKE=1) // フレームモードなし /* SPI3CON = 0; SPI3CONbits.FRMEN = 0; //フレーム制御OFF //Framed SPI support is disabled SPI3CONbits.ON = 1; //SPIモジュールON //SPI Peripheral is enabled SPI3CONbits.MODE32 = 0; //非32ビット転送 -->8ビット転送 //MODE32=0,MODE16=0,SPI3CONbits.AUDEN=0 が3つ共0なので8ビット転送 SPI3CONbits.MODE16 = 0; //非16ビット転送 SPI3CONbits.SMP = 0; //出力データ中央でサンプリング//Input data sampled at middle of data output time SPI3CONbits.CKE = 0; //クロックがアイドル→アクティブ変化時検出 SPI3CONbits.SSEN = 0; //SSピン制御OFF SPI3CONbits.CKP = 0; //クロック:アクティブで1 //Idle state for clock is a low level; active state is a high level SPI3CONbits.MSTEN = 1; //マスターモード SPI3CONbits.STXISEL = 0; //SPIxTXIF is set when the last transfer is shifted out of SPISR and transmit operations are complete SPI3CONbits.SRXISEL = 0; //SPIxRXIF is set when the last word in the receive buffer is read */ //SPI周波数 = ペリフェラル周波数 ÷ 2 ÷(BRG + 1) SPI3BRG = 0x000F; //SPI周波数: 2.5MHz( = 80MHz/2 ÷ (15 + 1) ) //SPI3BRG = 15; //5MHzはNG MP3_SPI_IF = 0; // 割り込みフラグクリア // RESET解除、VS1011スタート delay_ms(50); // 50msec delay MP3_XRESET_IO = 1; // RESET解除 // モード設定 CmdCheck(0x00, 0x08, 0x20); // モード初期設定 新モード、SDIテストモード // クロックダブラ設定 val = 12288 / 2 + 0x8000; // 設定値を求める(データシートより) CmdCheck(0x03, (BYTE)(val /256), (BYTE)val); delay_ms(10); } /******************************************** * VS1011 正弦波テストモード設定関数 * MODEをSPIテストモードに設定しておく必要がある *********************************************/ void VS1011_SineTest(void) { /* テストモードシーケンス出力 */ while(!MP3_DREQ_IO); MP3_XDCS_IO = 0; // Start Sine Test WriteSPI(0x53); WriteSPI(0xEF); WriteSPI(0x6E); WriteSPI(0x7D); // 22.050kHz Out is 5kHz WriteSPI(0x00); WriteSPI(0x00); WriteSPI(0x00); WriteSPI(0x00); MP3_XDCS_IO = 1; } /* //usec単位ディレイ関数 void delay_us(int usec){ usec = (int)(CLOCK*usec)/ 10; while(usec) { asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); usec--; } } //msec単位ディレイ関数 void delay_ms(int msec){ int i; for(i=0; i< msec; i++) delay_us(1000); } */ //--------------------------------------------------------------------------------------------------------- //************************************************************************* //インクルードファイル 1lcd_lib_C32.h //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //C32コンパイラ対応等で変更したものです。 //************************************************************************* #include <proc/p32mx795f512l.h> //PIC32MX460F512L #define Clock 80000000 // 単位はHzで指定 // LCDポート設定 #define lcd_port_DB7 LATBbits.LATB15 //LCDのDB7(14番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB6 LATBbits.LATB14 //LCDのDB6(13番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB5 LATBbits.LATB13 //のDB5(12番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB4 LATBbits.LATB12 //LCDのDB4(11番ピン)に接続されつPIC側ポート番号設定 #define lcd_rs LATAbits.LATA9 //LCDのrs(4番ピン)に接続されるPIC側ポート番号設定 #define lcd_stb LATAbits.LATA10 //LCDのstb(6番ピン)に接続されるPIC側ポート番号設定 void lcd_out(char code, char flag); void lcd_data(char asci); void lcd_cmd(char cmd); void lcd_clear(void); void lcd_init(void); void lcd_str(char *str); //----------------------------------------------------------------------------------------------------------------------- //************************************************************************** //インクルードファイル 1lcd_lib_C32.c //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //C32コンパイラ対応等で変更したものです。 //************************************************************************** /////////////////////////////////////////////// // 液晶表示器制御ライブラリ for C32コンパイラー // 内蔵関数は以下 // lcd_init() ----- 初期化 // lcd_cmd(cmd) ----- コマンド出力 // lcd_data(chr) ----- 1文字表示出力 // lcd_clear() ----- 全消去 // lcd_str(str*) ----- 文字列表示 ////////////////////////////////////////////// #include "1lcd_lib_C32.h" void lcd_delay_us(unsigned int usec) //1μsec遅延関数 { int count; count = (int)(Clock/20000000)*usec; do { asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); count--; }while(count != 0); } void lcd_delay_ms(unsigned int msec) //1msec遅延関数 { unsigned int i; for(i=0; i<msec; i++) lcd_delay_us(1000); } //////// データ出力サブ関数 void lcd_out(char code, char flag) { if(code & 0b10000000)lcd_port_DB7 = 1; //LCDのDB7への出力セット else lcd_port_DB7 = 0; if(code & 0b01000000)lcd_port_DB6 = 1; //LCDのDB6への出力セット else lcd_port_DB6 = 0; if(code & 0b00100000)lcd_port_DB5 = 1; //LCDのDB5への出力セット else lcd_port_DB5 = 0; if(code & 0b00010000)lcd_port_DB4 = 1; //LCDのDB4への出力セット else lcd_port_DB4 = 0; if (flag == 0) lcd_rs = 1; // 表示データの場合 else lcd_rs = 0; // コマンドデータの場合 lcd_delay_us(1); //1μsecウェイト lcd_stb = 1; // strobe(E) ON (Enable) lcd_delay_us(1); // 1μsec : strobe信号の幅 lcd_stb = 0; // reset strobe } //////// 1文字表示関数 void lcd_data(char asci) { lcd_out(asci, 0); // 上位4ビット出力 lcd_out(asci<<4, 0); // 下位4ビット出力 lcd_delay_us(50); //50μsecウェイト } /////// コマンド出力関数 void lcd_cmd(char cmd) { lcd_out(cmd, 1); // 上位4ビット出力 lcd_out(cmd<<4, 1); // 下位4ビット出力 if((cmd & 0x03) != 0) // clear Homeの場合 lcd_delay_ms(2); // 2msec待ち else lcd_delay_us(50); //50μsecウェイト } /////// 全消去関数 void lcd_clear(void) { lcd_cmd(0x01); // 初期化コマンド出力 } /////// 文字列出力関数 void lcd_str(char* str) { while(*str) //文字列終端の '\0'を検出するまで { lcd_data(*str); // 1文字表示 str++; //ポインタをインクリメント } } /////// 初期化関数 void lcd_init(void) { lcd_delay_ms(20); //20msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(5); //5msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(1); //1msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(1); //1msecウェイト lcd_out(0x20, 1); // 4bit mode set lcd_delay_ms(1); //1msecウェイト lcd_cmd(0x2E); // DL=0 4bit mode lcd_cmd(0x08); // display off C=D=B=0 lcd_cmd(0x0D); // display on C=D=1 B=0 lcd_cmd(0x06); // entry I/D=1 S=0 lcd_cmd(0x02); // cursor home }
//その他 FAT、グラフィックライブラリ関連のインクルードファイルは下記にあります。 //マイクロチップのライブラリダウンロードページ: Microchip Libraries for Applications 私がつかったバージョンは \microchip_solutions_v2013-02-15 です。 //GDDX関連のファイルは Microchip Graphics Display Designer X からダウンロードできます。 私がつかったバージョンは GDDX v.1.10 です //グラフィック液晶INT035TFTの関連情報は Displaytechのホームページ 及び DisplaytechのForum にあります。
<動作結果>
動作中の試作品全体 | ![]() |
EDENEAST.MP3(エデンの東)を再生中の画面です。 | ![]() |
液晶画面のアップ画像です。 ・起動するとSDカードのルートディレクトリにある ファイルを10個だけ表示します。 ・ ファイルのスクロール機能はありません ・ サブフォルダのファイルは表示できません ・Play/Stop ボタンをクリックすることにより、 再生を開始て/停止(pause)します。 ・ボタンの下にあるスライダー ウィジェットを ドラッグして音量が可変できます。 |
|
液晶にタッチしたところです。 ・キャラクタ液晶の下段に液晶画面の左上隅を 原点とするタッチ位置の座標系( X = 0〜320、Y = 0〜240)の タッチ位置 (196,170) が 表示されています。 |
![]() |
キャラクタ液晶の拡大画像です。 ・V=12は 再生している音量レベルです。 V = 0で音量最小、V = 100で音量最大を表します。 ・上段は再生中のファイル名です。 |
![]() |
試作したGDDXタッチパネル式 wav録音付MP3プレーヤで 作成した音声です。PCで再生してみてください。 |
VOICE.WAV |